#include "stdafx.h"
#include "Item.h"

#include "../db/Item.h"
#include "Property.h"

#include <utility/Streams.h>

#ifdef WIN32
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#endif

namespace serika
{
	namespace dq
	{
		Item::Item(db::Item* item, TransientState::Enum state)
		{
			mDbItem = new DbItem(item, state);
		}

		Item::~Item()
		{
			delete mDbItem;

			for (Properties::iterator iter = mProperties.begin();
				iter != mProperties.end(); ++iter)
			{
				delete (*iter);
			}
			mProperties.clear();
		}

		// static
		Item* Item::NewItem(int itemType, int buyPrice, int sellPrice, 
			const ut::String& chinessName, const ut::String& japanessName)
		{
			db::Item* item = new db::Item;

			item->SetValue("item_type", itemType);
			item->SetValue("buy_price", buyPrice);
			item->SetValue("sell_price", sellPrice);
			item->SetValue("chiness_name", chinessName);
			item->SetValue("japaness_name", japanessName);

			return new Item(item, TransientState::New);
		}

		// static
		Item* Item::FromDb(db::Item* item)
		{
			return new Item(item, TransientState::Clean);
		}

		Item* Item::FromDb(db::Item* item, const Properties& properties)
		{
			Item* newItem = new Item(item, TransientState::Clean);
			newItem->AddProperty(properties);
			return newItem;
		}

		int Item::GetId() const
		{
			return mDbItem->GetInt("id");
		}

		int Item::GetItemType() const
		{
			return mDbItem->GetInt("item_type");
		}

		int Item::GetBuyPrice() const
		{
			return mDbItem->GetInt("buy_price");
		}

		int Item::GetSellPrice() const
		{
			return mDbItem->GetInt("sell_price");
		}

		const ut::String& Item::GetChinessName() const
		{
			return mDbItem->GetString("chiness_name");
		}

		const ut::String& Item::GetJapanessName() const
		{
			return mDbItem->GetString("japaness_name");
		}

		void Item::SetItemType(int itemType)
		{
			mDbItem->Set("item_type", itemType);
		}

		void Item::SetBuyPrice(int buyPrice)
		{
			mDbItem->Set("buy_price", buyPrice);
		}

		void Item::SetSellPrice(int sellPrice)
		{
			mDbItem->Set("sell_price", sellPrice);
		}

		void Item::SetChinessName(const ut::String& name)
		{
			mDbItem->Set("chiness_name", name);
		}

		void Item::SetJapanessName(const ut::String& name)
		{
			mDbItem->Set("japaness_name", name);
		}

		ut::String Item::GetPropertyIds() const
		{
			return mDbItem->GetString("properties");
		}

		const std::vector<Property*>& Item::GetProperties() const
		{
			return mProperties;
		}

		void Item::AddProperty(const Properties& properties)
		{
			mProperties.insert(mProperties.end(), properties.begin(), properties.end());
		}

		void Item::AddProperty(Property* itemProperty)
		{
			itemProperty->SetItemId(this->GetId());
			mProperties.push_back(itemProperty);
		}

		void Item::Save()
		{
			for (Properties::iterator iter = mProperties.begin();
				iter != mProperties.end(); ++iter)
			{
				(*iter)->Save();
			}

			const ut::String& oldIds = this->GetPropertyIds();
			ut::String newIds;
			this->FormPropertiesString(newIds);
			if (oldIds != newIds)
			{
				mDbItem->Set("properties", newIds);
			}
			mDbItem->Save();
		}

		void Item::Delete()
		{
		}

		void Item::FormPropertiesString(ut::String& ids) const
		{
			ut::Sstream ss;
			bool first = true;
			for (Properties::const_iterator iter = mProperties.begin();
				iter != mProperties.end(); ++iter)
			{
				if (first)
				{
					first = false;
				}
				else
				{
					ss << ",";
				}
				ss << (*iter)->GetId();
			}
			ids = ss.str();
		}

		void Item::DelProprety(Property* itemProperty)
		{
			for (Properties::iterator itr = mProperties.begin();
				itr != mProperties.end(); ++itr)
			{
				Property* p = *itr;
				if (p == itemProperty)
				{
					delete p;
					mProperties.erase(itr);
					return;
				}
			}
		}
	}
}
